﻿using System;
using System.Runtime.InteropServices;

namespace msilgc.common.Types
{
    [StructLayout(LayoutKind.Sequential)]
    public struct IntArray {
        public int array_length;
        public IntPtr array_data;
    }
    public interface IPinnedMemoryResource : IDisposable
    {
        IntArray Data { get; }
    }
    public static class PinnedMemoryResource {
        public static PinnedMemoryResource<T> Create<T>(T[] managedArray) {
            return new PinnedMemoryResource<T>(managedArray);
        }
    }
    public class PinnedMemoryResource<T> : IPinnedMemoryResource
    {
        public IntArray Data { get; private set; }
        private GCHandle Handle { get; set; }
        public PinnedMemoryResource(T[] managedArray)
        {
            Handle = GCHandle.Alloc(managedArray, GCHandleType.Pinned);
            Data = new IntArray
                       {
                           array_data = Handle.AddrOfPinnedObject(),
                           array_length = managedArray.Length,
                       };
        }

        public void Dispose()
        {
            Handle.Free();
        }
    }

}